package com.cff.util;

import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.Properties;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.net.util.Base64;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.x509.RSAPublicKeyStructure;
import org.junit.After;
import org.junit.Before;

import com.jpre.packet.Coder;
import com.ums.common.hsm.HSMException;
import com.ums.common.hsm.HSMExecutorServiceImpl;
import com.ums.common.hsm.HSMImpl;
import com.ums.common.hsm.HSMUtil;

public class SignTools {
    private String hsmIp = "";
    private String hsmPort = "";
    private String destIp = "";
    private String destPort = "";
    private static Properties confPro = null;
    HSMExecutorServiceImpl exec;
	HSMImpl hsm;
	
	public String getHsmIp() {
		return hsmIp;
	}

	public void setHsmIp(String hsmIp) {
		this.hsmIp = hsmIp;
	}

	public String getHsmPort() {
		return hsmPort;
	}

	public void setHsmPort(String hsmPort) {
		this.hsmPort = hsmPort;
	}

	public String getDestIp() {
		return destIp;
	}

	public void setDestIp(String destIp) {
		this.destIp = destIp;
	}

	public String getDestPort() {
		return destPort;
	}

	public void setDestPort(String destPort) {
		this.destPort = destPort;
	}

	@Before
	public void init() {
		confPro = FileUtil.getInstance();
		hsmIp = confPro.getProperty("hsmip");
		hsmPort = confPro.getProperty("hsmport");
		destIp = confPro.getProperty("app12ip");
		destPort = confPro.getProperty("app12port");
		exec = new HSMExecutorServiceImpl(new String[] { hsmIp+":"+hsmPort });
		exec.init();
		hsm = new HSMImpl();
		hsm.setExec(exec);
	}
	
	@After
	public void destroy() {
		exec.shutdown();
	}
	
	public String publicEncrypt(String text, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		PublicKey publicKey = generatePublicKeyFromDer(key);
		init();
		System.out.println(HSMUtil.byteArr2HexString(publicKey.getEncoded()));
		Cipher cipher = Cipher.getInstance("RSA");
		System.out.println("\n" + cipher.getProvider().getInfo());
		// 使用公钥对明文进行加密
		System.out.println("\nStart encryption");
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		byte[] cipherText = cipher.doFinal(text.getBytes());
		String result = HSMUtil.byteArr2HexString(cipherText);
		System.out.println(result);
		destroy();
		return result;
	}
	
	/**
	 * 从Der格式公钥生成公钥
	 * 
	 * @param publicKeyDer
	 *            Der格式公钥字符串
	 * @return 公钥
	 */
	public static PublicKey generatePublicKeyFromDer(String publicKeyDer) {
		try {
			ASN1InputStream in = new ASN1InputStream(HSMUtil.hexString2ByteArr(publicKeyDer));
			RSAPublicKeyStructure pStruct = RSAPublicKeyStructure.getInstance(in.readObject());
			RSAPublicKeySpec spec = new RSAPublicKeySpec(pStruct.getModulus(), pStruct.getPublicExponent());
			KeyFactory kf = KeyFactory.getInstance("RSA");
			if (in != null)
				in.close();
			return kf.generatePublic(spec);
		} catch (Exception e) {
			return null;
		}
	}

	public String privateDecrypt(String text, String key) throws NumberFormatException, HSMException {
		System.out.println("私钥："+key);
		init();
		hsm.setPrivateKey(key);
		byte[] rsp = hsm.deRSAPaddingDataUsePriKey(Coder.hexStr2byte(text));
		destroy();
		return new String(rsp);
	}
	
}
